package com.yfp.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.util.StringUtil;
import com.yfp.client.domain.*;
import com.yfp.client.domain.dto.*;
import com.yfp.client.domain.vo.*;
import com.yfp.client.enums.*;
import com.yfp.client.mapper.*;
import com.yfp.client.service.*;
import com.yfp.client.domain.*;
import com.yfp.client.domain.dto.*;
import com.yfp.client.domain.vo.*;
import com.yfp.client.enums.*;
import com.yfp.client.mapper.*;
import com.yfp.client.service.*;
import com.yfp.client.service.impl.couponStrategy.ClientCouponStrategy;
import com.yfp.client.service.impl.couponStrategy.ClientCouponStrategyFactory;
import com.yfp.client.util.RedisDistributedLock;
import com.yfp.client.util.RedisKey;
import com.yfp.client.util.ResponseEnum;
import com.yfp.client.util.SecurityUtils;
import com.yfp.common.core.constant.CacheConstants;
import com.yfp.common.core.exception.InnerAuthException;
import com.yfp.common.core.utils.DateUtils;
import com.yfp.common.redis.service.RedisService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 客户优惠券
 *
 * @CreateDate: 2024/7/16 18:59
 * @UpdateUser:
 * @UpdateDate: 2024/7/16 18:59
 * @UpdateRemark: 暂无修改
 * @Version: 1.0
 */
@Service
@Slf4j
public class ClientCouponServiceImpl implements ClientCouponService {
    @Autowired
    private ClientCouponMapper clientCouponMapper;
    @Autowired
    private MarCouponService marCouponService;
    @Resource
    private MarCouponComboMapper marCouponComboMapper;
    @Resource
    private MarCouponPositionMapper marCouponPositionMapper;
    @Resource
    private ClientCouponStrategyFactory clientCouponStrategyFactory;
    @Autowired
    private ClientActivityService clientActivityService;
    @Autowired
    private RedisService redisService;
    @Autowired
    public RedisTemplate redisTemplate;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private MachineService machineService;
    @Autowired
    private MiniBannerService miniBannerService;
    @Autowired
    private MarActivityService marActivityService;
    @Autowired
    private ClientService clientService;
    @Autowired
    private MarActivityClientService marActivityClientService;
    @Autowired
    private OrderComboService orderComboService;
    @Autowired
    private MarActivityDetailsMapper marActivityDetailsMapper;
    @Autowired
    private MarCouponMapper marCouponMapper;
    @Resource
    private ComboService comboService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderListService orderListService;
    @Resource
    private PositionMapper positionMapper;
    @Autowired
    private MarCouponPackDetailsService marCouponPackDetailsService;
    @Autowired
    private MarCouponPackService marCouponPackService;


    /**
     * 查询优惠券
     *
     * @param couponId
     * @param clientId
     * @return
     */
    @Override
    public ClientCoupon findByCouponIdAndClientId(Long couponId, String clientId) {
        return clientCouponMapper.findByCouponIdAndClientId(couponId, clientId);
    }

    @Override
    public ClientCoupon findByIdAndClientId(Long id, String clientId) {
        return clientCouponMapper.findByIdAndClientId(id, clientId);
    }

    /**
     * 查询优惠券
     *
     * @param Id
     * @return
     */
    @Override
    public ClientCoupon findById(Long Id) {
        return clientCouponMapper.findById(Id);
    }

    /**
     * 是否弹窗领券
     *
     * @return
     */
    @Override
    @Transactional
    public PopupVO popup(String clientId, String cityName) {
        log.info("弹窗参数:{},{}", clientId, cityName);
        PopupVO popupVO = new PopupVO();
        popupVO.setStatus(0);
        List<MiniBanner> miniBanners = miniBannerService.findPopup(cityName);
        if (CollectionUtils.isEmpty(miniBanners)) {
            popupVO.setStatus(0);
            return popupVO;
        }
        List<Long> marketingIds = miniBanners.stream().map(s -> s.getMarketingId()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(marketingIds)) {
            popupVO.setStatus(0);
            return popupVO;
        }

        // 点位标签
        String lastPositionId = null;
        // 有标签则取，没标签则取最后一单的点位
        Client client = clientService.getById(clientId);
        if (!BeanUtil.isEmpty(client) && !StringUtil.isEmpty(client.getPositionId())) {
            lastPositionId = client.getPositionId();
        } else {
            lastPositionId = orderListService.findLastPositionIdByClinetId(clientId);
            // 给用户打点位标签
            if (!StringUtil.isEmpty(lastPositionId)) {
                clientService.updatePositionId(clientId, lastPositionId);
            }
        }


        // 1特殊 2普通
        Integer label = null;
        if (!StringUtil.isEmpty(lastPositionId)) {
            label = positionMapper.getLabel(lastPositionId);
        }
        for (MiniBanner miniBanner : miniBanners) {

            log.info("bannerId:{}",miniBanner.getId());
            log.info("miniBanner.getMarketingId:  {}", miniBanner.getMarketingId());
            Marketing marketing = clientActivityService.findMarketingById(miniBanner.getMarketingId());
            if (null == marketing) {
                popupVO.setStatus(0);
                continue;
            }

            List<MiniBannerPosition> miniBannerPositions = miniBannerService.findByMiniBannerId(miniBanner.getId());
            List<String> positioinIds = miniBannerPositions.stream().map(s -> s.getPositionId()).collect(Collectors.toList());
            log.info("positioinIds: {} , lastPositionId：{}", JSONObject.toJSONString(positioinIds), lastPositionId);


            if (StringUtil.isEmpty(lastPositionId) && miniBanner.getPositionType() == 1) {
                log.info("没有点位标签且banner为普通全部");
                String faquan = faquan(marketing, popupVO, clientId, cityName, miniBanner);
                if (faquan != null && "continue".equals(faquan)) {
                    continue;
                } else if (faquan != null && "break".equals(faquan)) {
                    break;
                }
            } else if (!CollectionUtils.isEmpty(positioinIds) && positioinIds.contains(lastPositionId) && miniBanner.getPositionType() == 2 && label == 2) {
                log.info("有点位标签且存在点位关系，点位标签为普通，banner为普通指定");
                String faquan = faquan(marketing, popupVO, clientId, cityName, miniBanner);
                if (faquan != null && "continue".equals(faquan)) {
                    continue;
                } else if (faquan != null && "break".equals(faquan)) {
                    break;
                }
            }else if (!CollectionUtils.isEmpty(positioinIds) && positioinIds.contains(lastPositionId) && miniBanner.getPositionType() == 4 && label == 1) {
                log.info("有点位标签且存在点位关系，点位标签为特殊，banner为特殊指定");
                String faquan = faquan(marketing, popupVO, clientId, cityName, miniBanner);
                if (faquan != null && "continue".equals(faquan)) {
                    continue;
                } else if (faquan != null && "break".equals(faquan)) {
                    break;
                }
            } else if (CollectionUtils.isEmpty(positioinIds) && miniBanner.getPositionType() == 1 && label != null && label == 2) {
                log.info("有点位标签无点位关系，点位标签为普通，banner为普通全部");
                String faquan = faquan(marketing, popupVO, clientId, cityName, miniBanner);
                if (faquan != null && "continue".equals(faquan)) {
                    continue;
                } else if (faquan != null && "break".equals(faquan)) {
                    break;
                }
            } else if (CollectionUtils.isEmpty(positioinIds) && miniBanner.getPositionType() == 3 && label != null && label == 1) {
                log.info("有点位标签无点位关系，点位标签为特殊，banner为特殊全部");
                String faquan = faquan(marketing, popupVO, clientId, cityName, miniBanner);
                if (faquan != null && "continue".equals(faquan)) {
                    continue;
                } else if (faquan != null && "break".equals(faquan)) {
                    break;
                }
            }

//            if (CollectionUtils.isEmpty(positioinIds) || positioinIds.contains(lastPositionId) || miniBanner.getPositionType() == 0) {
//                ResponseEnum responseEnum = null;
//                if (MarketingTypeEnum.COUPON.getType() == marketing.getType()) {
//                    // 优惠券
//                    MarCoupon marCoupon = marCouponService.findById(marketing.getMarCouponId());
//                    Integer couponCount = clientCouponMapper.countByClientIdAndCouponIdAndMiniBannerId(clientId, marCoupon.getId(), miniBanner.getId());
//                    if (couponCount > 0 || (marCoupon.getStatus() != 1 && marCoupon.getStatus() != 4)) {
//                        popupVO.setStatus(0);
//                        continue;
//                    }
//                    log.info("弹窗发券 ClientId：{}，marCouponId：{}，couponCount：{}", clientId, marCoupon.getId(), couponCount);
//                    responseEnum = verifyCoupon(marCoupon.getId(), clientId, null, cityName, miniBanner.getId(), null);
//                    log.info("发券结果", responseEnum);
//                    if (responseEnum.getCode() == ResponseEnum.OPERATOR_SUCCESS.getCode()) {
//                        popupVO.setStatus(1);
//                        popupVO.setUrl(miniBanner.getUrl());
//                        popupVO.setImg(miniBanner.getImg());
//                        popupVO.setMarketingId(marketing.getId());
////                        List<String> couponIds = clientCouponMapper.findCouponSysDictData();
////                        for (String couponId : couponIds) {
////                            verifyCoupon(Long.parseLong(couponId), clientId, null, cityName);
////                        }
//                        break;
//                    } else {
//                        popupVO.setStatus(0);
//                    }
//                } else if (MarketingTypeEnum.COUPONPACK.getType() == marketing.getType()) {
//                    // 优惠券礼包
//                    boolean result = acquireCouponPack(marketing.getId(), clientId, cityName, miniBanner.getId());
//                    if (result) {
//                        popupVO.setStatus(1);
//                        popupVO.setUrl(miniBanner.getUrl());
//                        popupVO.setImg(miniBanner.getImg());
//                        popupVO.setMarketingId(marketing.getId());
//                        break;
//                    } else {
//                        popupVO.setStatus(0);
//                    }
//                }
//            }
        }
        return popupVO;
    }



    public String faquan(Marketing marketing,PopupVO popupVO,String clientId, String cityName, MiniBanner miniBanner){
            ResponseEnum responseEnum = null;
            if (MarketingTypeEnum.COUPON.getType() == marketing.getType()) {
                // 优惠券
                MarCoupon marCoupon = marCouponService.findById(marketing.getMarCouponId());
                Integer couponCount = clientCouponMapper.countByClientIdAndCouponIdAndMiniBannerId(clientId, marCoupon.getId(), miniBanner.getId());
                if (couponCount > 0 || (marCoupon.getStatus() != 1 && marCoupon.getStatus() != 4)) {
                    popupVO.setStatus(0);
                    return "continue";
                }
                log.info("弹窗发券 ClientId：{}，marCouponId：{}，couponCount：{}", clientId, marCoupon.getId(), couponCount);
                responseEnum = verifyCoupon(marCoupon.getId(), clientId, null, cityName, miniBanner.getId(), null);
                log.info("发券结果", responseEnum);
                if (responseEnum.getCode() == ResponseEnum.OPERATOR_SUCCESS.getCode()) {
                    popupVO.setStatus(1);
                    popupVO.setUrl(miniBanner.getUrl());
                    popupVO.setImg(miniBanner.getImg());
                    popupVO.setMarketingId(marketing.getId());
//                        List<String> couponIds = clientCouponMapper.findCouponSysDictData();
//                        for (String couponId : couponIds) {
//                            verifyCoupon(Long.parseLong(couponId), clientId, null, cityName);
//                        }
                    return "break";
                } else {
                    popupVO.setStatus(0);
                }
            } else if (MarketingTypeEnum.COUPONPACK.getType() == marketing.getType()) {
                // 优惠券礼包
                boolean result = acquireCouponPack(marketing.getId(), clientId, cityName, miniBanner.getId());
                if (result) {
                    popupVO.setStatus(1);
                    popupVO.setUrl(miniBanner.getUrl());
                    popupVO.setImg(miniBanner.getImg());
                    popupVO.setMarketingId(marketing.getId());
                    return "break";
                } else {
                    popupVO.setStatus(0);
                }
            }
        return null;
    }






    @Override
    public boolean acquireCouponPack(Long marketingId, String clientId, String cityName, Long miniBannerId) {
        log.info("====marketingId：{}，clientId：{}, cityName ： {} ====", marketingId, clientId, cityName);
        boolean acquireResult = false;
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, "couponPackId:" + RedisKey.COUPONLOCK, 10);
        try {
            // 加锁
            redisDistributedLock.lock();
            // 优惠券礼包
            MarCouponPack marCouponPack = marCouponPackService.findByMarketingId(marketingId);
            if (marCouponPack.getStatus() != 1 || marCouponPack.getSurplusCount() <= 0) {
                return false;
            }
            int countCouponPack = 0;
            if (null != miniBannerId) {
                countCouponPack = clientCouponMapper.countByCouponPackIdAndClientIdInt(marCouponPack.getId(), clientId);
            } else {
                countCouponPack = clientCouponMapper.countByCouponPackIdAndClientIdAndMiniBannerId(marCouponPack.getId(), clientId, miniBannerId);
            }
            if (countCouponPack > 0) {
                return false;
            }
//            MarCouponPack marCouponPack = marCouponPackService.findById(marketingId);
            List<MarCouponPackDetails> marCouponPackDetails = marCouponPackDetailsService.findByCouponPackId(marCouponPack.getId());
            if (marCouponPack.getFailureCondition() == 1) {
                // 全部满足才发放
                log.info("====全部满足才发放====");
                boolean result = false;
                for (MarCouponPackDetails marCouponPackDetail : marCouponPackDetails) {
                    MarCoupon marCoupon = marCouponService.findById(marCouponPackDetail.getCouponId());
                    result = verifyCouponBoolean(marCoupon.getId(), clientId, cityName);
                    if (result == false) {
                        return result;
                    }
                }
                for (MarCouponPackDetails marCouponPackDetail : marCouponPackDetails) {
                    MarCoupon marCoupon = marCouponService.findById(marCouponPackDetail.getCouponId());
                    for (int i = 0; i < marCouponPackDetail.getCouponCount(); i++) {
                        verifyCoupon(marCoupon.getId(), clientId, marCouponPack.getId(), cityName, miniBannerId, null);
                    }
                }
                acquireResult = true;
            } else {
                // 单张满足就发放
                log.info("====单张满足就发放====");
                for (MarCouponPackDetails marCouponPackDetail : marCouponPackDetails) {
                    MarCoupon marCoupon = marCouponService.findById(marCouponPackDetail.getCouponId());
                    for (int i = 0; i < marCouponPackDetail.getCouponCount(); i++) {
                        ResponseEnum responseEnum1 = verifyCoupon(marCoupon.getId(), clientId, marCouponPack.getId(), cityName, miniBannerId, null);
                        if (responseEnum1.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
                            acquireResult = true;
                        }
                    }
                }
            }
            if (acquireResult) {
                marCouponPackService.editSurplusCount(marCouponPack.getId());
            }
        } catch (Exception e) {
            log.info("出现异常， 异常信息：{}", e.getMessage());
        } finally {
            redisDistributedLock.unlock();
        }
        return acquireResult;
    }

    @Override
    @Transactional
    public ResponseEnum acquire(Long couponId, String clientId, String cityName) {
        // 领取超过限额
        List<Integer> statusList = new ArrayList<>();
        statusList.add(ClientCouponStatusEnums.NORMAL.getCode());
        statusList.add(ClientCouponStatusEnums.NOT_STARTED.getCode());
        int countCoupon = clientCouponMapper.countByClientIdAndCouponId(SecurityUtils.getClientId(), null, statusList);
        if (countCoupon >= 200) {
            return ResponseEnum.COUPON_EXCEED;
        }
        return verifyCoupon(couponId, clientId, null, cityName, null, null);
    }

    @Transactional
    @Override
    public ResponseEnum activiryAcquire(ActiviryAcquireDTO activiryAcquireDTO) {
        // 领取超过限额
        Marketing marketing = clientActivityService.findMarketingById(activiryAcquireDTO.getMarketingId());
        if (null == marketing) {
            return ResponseEnum.COUPON_NOT_EXIST;
        }
        if (MarketingTypeEnum.COUPON.getType() == marketing.getType()) {
            // 优惠券活动
            List<Integer> statusList = new ArrayList<>();
            statusList.add(ClientCouponStatusEnums.NORMAL.getCode());
            statusList.add(ClientCouponStatusEnums.NOT_STARTED.getCode());
            int countCoupon = clientCouponMapper.countByClientIdAndCouponId(SecurityUtils.getClientId(), null, statusList);
            if (countCoupon >= 200) {
                return ResponseEnum.COUPON_EXCEED;
            }
            ResponseEnum responseEnum = verifyCoupon(marketing.getMarCouponId(), activiryAcquireDTO.getClientId(), null, activiryAcquireDTO.getCityName(), null, null);
            return responseEnum;
        } else {
            // 活动
            MarActivity marActivity = marActivityService.findById(marketing.getMarActivityId());
            if (null != activiryAcquireDTO.getCityName() && !activiryAcquireDTO.getCityName().equals(marActivity.getCityName())) {
                return ResponseEnum.COUPON_NOT_CITY;
            }
            ResponseEnum responseEnum = null;
            MarActivityClient marActivityClient = new MarActivityClient();
            if (marActivity.getType() == ActivityTypeEnum.NEW_RECRUITMENT_ACTIVITIES.getType()) {
                Client client = clientService.getById(activiryAcquireDTO.getClientId());
                if (Objects.isNull(client) || "".equals(client.getInvitationClientId()) || !activiryAcquireDTO.getInvitationClientId().equals(client.getInvitationClientId())) {
                    return ResponseEnum.NOT_INVITATION;
                }

                marActivityClient.setHostClientId(activiryAcquireDTO.getInvitationClientId());
                marActivityClient.setPassiveClientId(SecurityUtils.getClientId());
                marActivityClient.setMarActivityId(marActivity.getId());
                int count = marActivityClientService.count(marActivityClient);
                if (count != 0) {
                    return ResponseEnum.NOT_PARTICIPATE_IN_ACTIVITY;
                }
                // 发放邀请人奖励
//                ResponseEnum responseEnum2 = null;
//                List<MarActivityDetails> marActivityDetailsList = marActivityService.findMarActivityDetailsByMarActivityId(marActivity.getId());
//                for (MarActivityDetails marActivityDetails : marActivityDetailsList) {
//                    responseEnum2 = verifyCoupon(marActivityDetails.getHostMarCouponId(), activiryAcquireDTO.getInvitationClientId());
//                }
//                if (responseEnum2.getCode().equals(ResponseEnum.OPERATOR_SUCCESS.getCode())) {
//                    marActivityClient.setStatus(1);
//                } else {
//                    marActivityClient.setStatus(2);
//                }

                marActivityClient.setStatus(0);
                marActivityClient.setCreateTime(new Date());
                marActivityClientService.add(marActivityClient);
                PopupVO popup = popup(activiryAcquireDTO.getClientId(), activiryAcquireDTO.getCityName());
                if (popup.getStatus() == 1) {
                    responseEnum = ResponseEnum.OPERATOR_SUCCESS;
                } else {
                    responseEnum = ResponseEnum.NOT_PARTICIPATE_IN_ACTIVITY;
                }
            } else {

                List<MarActivityDetails> marActivityDetailsList = marActivityService.findMarActivityDetailsByMarActivityId(marketing.getMarActivityId());
                // 优惠券
                for (MarActivityDetails marActivityDetails : marActivityDetailsList) {
                    Long couponId = 0L;
                    if (marActivity.getType() == ActivityTypeEnum.NEW_RECRUITMENT_ACTIVITIES.getType()) {
                        couponId = marActivityDetails.getPassiveMarCouponId();
                        marActivityClient.setPassiveClientId(activiryAcquireDTO.getClientId());
                    } else {
                        couponId = marActivityDetails.getHostMarCouponId();
                    }
                    ResponseEnum responseEnum2 = verifyCoupon(couponId, activiryAcquireDTO.getClientId(), null, activiryAcquireDTO.getCityName(), null, null);
                    if (responseEnum2.getCode() == ResponseEnum.OPERATOR_SUCCESS.getCode()) {
                        responseEnum = responseEnum2;
                    }
                }
                if (null != responseEnum && responseEnum.getCode() == ResponseEnum.OPERATOR_SUCCESS.getCode()) {
                    marActivityClient.setHostClientId(activiryAcquireDTO.getInvitationClientId());
                    marActivityClient.setMarActivityId(marActivity.getId());
                    marActivityClient.setCreateTime(new Date());
                    marActivityClient.setStatus(0);
                    marActivityClientService.add(marActivityClient);
                } else {
                    responseEnum = ResponseEnum.NOT_PARTICIPATE_IN_ACTIVITY;
                }
            }
            return responseEnum;
        }
    }

    @Override
    public MarActivity activity(ActiviryAcquireDTO activiryAcquireDTO) {
        log.info("activity:{}", activiryAcquireDTO);
        Marketing marketing = clientActivityService.findMarketingById(activiryAcquireDTO.getMarketingId());
        if (null == marketing) {
            return null;
        }

        if (MarketingTypeEnum.ACTIVITY.getType().equals(marketing.getType())) {
            // 活动
            return marActivityService.findById(marketing.getMarActivityId());
        }

        return null;
    }

    /**
     * 发券
     *
     * @param couponId
     * @param clientId
     * @return
     */
    @Transactional
    @Override
    public ResponseEnum verifyCoupon(Long couponId, String clientId, Long couponPackId, String cityName, Long miniBannerId, Long cbId) {
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, RedisKey.COUPONLOCK, 10);
        try {
            // 加锁
            redisDistributedLock.lock();

            MarCoupon marCoupon = marCouponService.findById(couponId);

            // 优惠券不存在
            if (null == marCoupon) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_NOT_EXIST;
            }
            if (null != cityName && !cityName.equals(marCoupon.getCityName()) && !cityName.equals("全国")) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_NOT_CITY;
            }
            // 优惠券删除或者优惠券失效
            if (marCoupon.getStatus() == 0 || marCoupon.getStatus() == 2 || marCoupon.getStatus() == 5) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_LOSE_EFFICACY;
            }

            // 优惠券剩余数量不足
            if (marCoupon.getSurplusCount() == 0) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_NOT_SURPLUS_COUNT;
            }
            // 最大领取
            int countCoupon = clientCouponMapper.countByClientIdAndCouponId(clientId, couponId, null);
            if (countCoupon >= marCoupon.getReceiveCount()) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_COUNT_EXCEED;
            }
            if (null != marCoupon.getValidDays() && marCoupon.getValidDays() != 0) {
                // 当前日期
                LocalDate currentDate = LocalDate.now();
                // 要添加的天数
                int daysToAdd = marCoupon.getValidDays();
                // 当前日期加上指定天数
                LocalDate newDate = currentDate.plusDays(daysToAdd);
                // 获取结果日期的起始时间（00:00:00）
                LocalDateTime startOfDay = newDate.atStartOfDay();
                LocalDateTime localDateTime = startOfDay.minusSeconds(1);
                Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
                // 转换为 Date
                Date date = Date.from(instant);
                marCoupon.setValidStartTime(new Date());
                marCoupon.setValidEndTime(date);
            }
            // 优惠券活动时间是否过期
            Date date = DateUtils.addDays(marCoupon.getValidEndTime(), marCoupon.getPostponeDay());
            if (date.getTime() < System.currentTimeMillis()) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_OVERDUE;
            }
            // 是否新用户
            if (marCoupon.getClientStatus() == 2) {
                Integer orderCount = orderComboService.countOrderByClientId(clientId);
                if (orderCount > 0) {
                    redisDistributedLock.unlock();
                    return ResponseEnum.COUPON_NEW_CLIENT;
                }
            }
            marCouponService.editSurplusCount(marCoupon.getId());

            ClientCoupon clientCoupon = new ClientCoupon();
            BeanUtils.copyProperties(marCoupon, clientCoupon);
            clientCoupon.setClientId(clientId);
            clientCoupon.setCouponId(couponId);
            clientCoupon.setCouponPackId(couponPackId);
            clientCoupon.setMiniBannerId(miniBannerId);
            if (cbId != null) {
                clientCoupon.setClientBillId(cbId);
            }
            clientCouponMapper.insert(clientCoupon);
            log.info("clientCouponId:{}", clientCoupon.getId());
            redisService.setCacheObject(MessageFormat.format(RedisKey.CLIENTCOUPON, clientId), clientCoupon.getId(), 1L, TimeUnit.MINUTES);
            return ResponseEnum.OPERATOR_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("领券异常：{}", e.getMessage());
        } finally {
            redisDistributedLock.unlock();
        }
        return ResponseEnum.OPERATOR_FAILUER;
    }

    @Override
    public ResponseEnum verification(Long couponId, String clientId) {
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, RedisKey.COUPONLOCK, 10);
        try {
            // 加锁
            redisDistributedLock.lock();

            MarCoupon marCoupon = marCouponService.findById(couponId);
            // 优惠券不存在
            if (null == marCoupon) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_NOT_EXIST;
            }
            // 优惠券删除或者优惠券失效
            if (marCoupon.getStatus() == 0 || marCoupon.getStatus() == 2 || marCoupon.getStatus() == 5) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_LOSE_EFFICACY;
            }

            // 最大领取
            int countCoupon = clientCouponMapper.countByClientIdAndCouponId(SecurityUtils.getClientId(), couponId, null);
            if (countCoupon >= marCoupon.getReceiveCount()) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_COUNT_EXCEED;
            }
            // 是否新用户
            if (marCoupon.getClientStatus() == 2) {
                Integer orderCount = orderComboService.countOrderByClientId(clientId);
                if (orderCount > 0) {
                    redisDistributedLock.unlock();
                    return ResponseEnum.COUPON_NEW_CLIENT;
                }
            }

            if (null != marCoupon.getValidDays() && marCoupon.getValidDays() != 0) {
                // 当前日期
                LocalDate currentDate = LocalDate.now();
                // 要添加的天数
                int daysToAdd = marCoupon.getValidDays();
                // 当前日期加上指定天数
                LocalDate newDate = currentDate.plusDays(daysToAdd);
                // 获取结果日期的起始时间（00:00:00）
                LocalDateTime startOfDay = newDate.atStartOfDay();
                LocalDateTime localDateTime = startOfDay.minusSeconds(1);
                Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
                // 转换为 Date
                Date date2 = Date.from(instant);
                marCoupon.setValidStartTime(new Date());
                marCoupon.setValidEndTime(date2);
            }

            // 优惠券活动时间是否过期
            Date date = DateUtils.addDays(marCoupon.getValidEndTime(), marCoupon.getPostponeDay());
            if (date.getTime() < System.currentTimeMillis()) {
                redisDistributedLock.unlock();
                return ResponseEnum.COUPON_OVERDUE;
            }
            ClientCoupon clientCoupon = new ClientCoupon();
            BeanUtils.copyProperties(marCoupon, clientCoupon);
            clientCoupon.setClientId(clientId);
            clientCoupon.setCouponId(couponId);
            clientCouponMapper.insert(clientCoupon);
            log.info("clientCouponId:{}", clientCoupon.getId());
            redisDistributedLock.unlock();
            redisService.setCacheObject(MessageFormat.format(RedisKey.CLIENTCOUPON, clientId), clientCoupon.getId(), 1L, TimeUnit.MINUTES);
            return ResponseEnum.OPERATOR_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("发券报错信息：{}", e.getMessage());
        } finally {
            redisDistributedLock.unlock();
        }
        return ResponseEnum.OPERATOR_FAILUER;
    }

    @Override
    public List<ClientCoupon> findListByStatusAndClientId(Integer status, String clientId) {
        log.info("findListByStatusAndClientId:{}", status);
        // 只查询已失效/过期7天内的优惠券
        if (ClientCouponStatusEnums.EXPIRED.getCode().equals(status)) {
            List<ClientCoupon> couponList = clientCouponMapper.findListByStatusAndClientIdAndDays(status, clientId, 7);
            return couponList;
        }

        // 只查询已失效/过期7天内的优惠券
        if (ClientCouponStatusEnums.INVALID.getCode().equals(status)) {
            List<ClientCoupon> couponList = clientCouponMapper.findListByInvalidStatusAndClientIdAndDays(status, clientId, 7);
            return couponList;
        }

        // 待使用
        List<ClientCoupon> couponList = clientCouponMapper.findListByStatusAndClientId(status, clientId);
        if (status == 1) {
            List<ClientCoupon> list = clientCouponMapper.findListByStatusAndClientId(ClientCouponStatusEnums.NOT_STARTED.getCode(), clientId);
            if (!list.isEmpty()) {
                couponList.addAll(list);
            }
        }
        return couponList;
    }

    @Override
    public boolean verifyCouponBoolean(Long couponId, String clientId, String cityName) {
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, RedisKey.COUPONLOCK, 10);
        try {
            // 加锁
            redisDistributedLock.lock();
            MarCoupon marCoupon = marCouponService.findById(couponId);
            if (null != marCoupon.getValidDays() && marCoupon.getValidDays() != 0) {
                // 当前日期
                LocalDate currentDate = LocalDate.now();
                // 要添加的天数
                int daysToAdd = marCoupon.getValidDays();
                // 当前日期加上指定天数
                LocalDate newDate = currentDate.plusDays(daysToAdd);
                // 获取结果日期的起始时间（00:00:00）
                LocalDateTime startOfDay = newDate.atStartOfDay();
                LocalDateTime localDateTime = startOfDay.minusSeconds(1);
                Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
                // 转换为 Date
                Date date = Date.from(instant);
                marCoupon.setValidStartTime(new Date());
                marCoupon.setValidEndTime(date);
            }
            if (null != cityName && !cityName.equals(marCoupon.getCityName())) {
                redisDistributedLock.unlock();
                return false;
            }
            // 优惠券不存在
            if (null == marCoupon) {
                redisDistributedLock.unlock();
                return false;
            }
            // 优惠券删除或者优惠券失效
            if (marCoupon.getStatus() == 0 || marCoupon.getStatus() == 2) {
                redisDistributedLock.unlock();
                return false;
            }
            // 优惠券是否过期
            Date date = DateUtils.addDays(marCoupon.getValidEndTime(), marCoupon.getPostponeDay());
            if (date.getTime() < System.currentTimeMillis()) {
                redisDistributedLock.unlock();
                return false;
            }
            // 优惠券剩余数量不足
            if (marCoupon.getSurplusCount() == 0) {
                redisDistributedLock.unlock();
                return false;
            }
            // 最大领取
            int countCoupon = clientCouponMapper.countByClientIdAndCouponId(clientId, couponId, null);
            if (countCoupon >= marCoupon.getReceiveCount()) {
                redisDistributedLock.unlock();
                return false;
            }
            // 是否新用户
            if (marCoupon.getClientStatus() == 2) {
                Integer orderCount = orderComboService.countOrderByClientId(clientId);
                if (orderCount > 0) {
                    redisDistributedLock.unlock();
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("领券异常：{}", e.getMessage());
        } finally {
            redisDistributedLock.unlock();
        }
        return false;
    }

    @Override
    public ClientCouponOrderVO getClientCouponOrderList(OrderCreateDTO orderCreateDTO) {
        String clientId = SecurityUtils.getClientId();
        // 按照设备区分城市
        String machineId = orderCreateDTO.getMachineId();
        Machine machine = machineService.findByMachineId(machineId);
        // String clientId = "3";
        log.info("订单详情-优惠券列表计算入参:{}", orderCreateDTO);
        // 用户所有的优惠券
        List<ClientCoupon> clientCouponList = clientCouponMapper.getClientCouponListByClientIdAndStatusType(clientId, ClientCouponStatusEnums.NORMAL.getCode(), machine.getCityName());
        List<ClientCoupon> notStartedCoupon = clientCouponMapper.getClientCouponListByClientIdAndStatusType(clientId, ClientCouponStatusEnums.NOT_STARTED.getCode(), machine.getCityName());
        // 获取用户可使用的优惠券列表
        List<ClientCoupon> availableCoupons = this.getAvailableCoupons(orderCreateDTO, clientCouponList);
        // 获取用户不可使用的优惠券列表
        List<ClientCoupon> unavailableCoupons = ListUtil.toList(CollUtil.subtractToList(clientCouponList, availableCoupons));
        unavailableCoupons.addAll(notStartedCoupon);
        return ClientCouponOrderVO.builder().availableCoupons(availableCoupons).unavailableCoupons(unavailableCoupons).build();
    }

    @Override
    public List<ClientCoupon> getAvailableCoupons(OrderCreateDTO orderCreateDTO, List<ClientCoupon> clientCoupons) {

        if (CollUtil.isEmpty(clientCoupons)) {
            return List.of();
        }

        // 获取餐品价格
        List<String> packageId = orderCreateDTO.getShoppingCartList().stream().map(ShoppingCartsDto::getPackageId).collect(Collectors.toList());
        Map<String, Combo> comboMapByComboId = comboService.listByPackageIds(packageId).stream().collect(Collectors.toMap(Combo::getComboId, Function.identity()));
        orderCreateDTO.getShoppingCartList().forEach(item -> {
            Combo combo = comboMapByComboId.getOrDefault(item.getPackageId(), null);
            Assert.notNull(combo, "套餐不存在，请重新结算");
            item.setPrice(new BigDecimal(combo.getSalePrice()));
        });

        DateTime nowDate = DateUtil.date();
        // 用户可使用的优惠券列表
        List<ClientCoupon> clientCouponList = clientCoupons.stream().filter(item -> {
            // 判断优惠券状态
            return ClientCouponStatusEnums.NORMAL.getCode().equals(item.getStatus());
        }).filter(item -> {
            // 判断优惠券有效开始时间、有效结束时间
            Date validEndTime = item.getValidEndTime();
            DateTime dateTime = DateUtil.offsetDay(validEndTime, item.getPostponeDay());
            return DateUtil.compare(item.getValidStartTime(), nowDate) <= 0 && DateUtil.compare(dateTime, nowDate) >= 0;
        }).filter(item -> {
            if (CouponTypeEnum.BABY_CUSTOMER.getCode().equals(item.getType())) {
                // 判断是否为霸王优惠券,霸王免单券只可用于购物车内存在1个餐品
                Integer quantity = orderCreateDTO.getShoppingCartList().stream().map(ShoppingCartsDto::getQuantity).reduce(Integer::sum).get();
                return !(quantity > 1);
            }
            return true;
        }).collect(Collectors.toList());

        if (CollUtil.isEmpty(clientCouponList)) {
            return List.of();
        }
        List<Long> couponIds = clientCouponList.stream().map(ClientCoupon::getCouponId).collect(Collectors.toList());
        Map<Long, List<MarCouponPosition>> marCouponPositionMapByCouponId = marCouponPositionMapper.selectByMarCouponIds(couponIds).stream().collect(Collectors.groupingBy(MarCouponPosition::getMarCouponId));
        Machine machine = machineService.findByMachineId(orderCreateDTO.getMachineId());
        Position position = positionMapper.positionIdAndLabel(machine.getPositionId());
        clientCouponList = clientCouponList.stream().filter(item -> {
            // 判断优惠券适用点位
            if (item.getPosition() == 4) {
                return true;
            }
            if (position.getLabel() == 1 && item.getPosition() == 2) {
                return true;
            }
            if (position.getLabel() == 2 && item.getPosition() == 0) {
                return true;
            }

            MarCouponPosition marCouponPosition = marCouponPositionMapper.getByPositionIdAndLabel(item.getCouponId(), position.getPositionId());
            if (!BeanUtil.isEmpty(marCouponPosition)) {
                return true;
            }

            List<String> tempPositions = marCouponPositionMapByCouponId.getOrDefault(item.getCouponId(), List.of()).stream().map(MarCouponPosition::getPositionId).collect(Collectors.toList());
            return CollUtil.containsAny(tempPositions, List.of(machine.getPositionId()));

        }).collect(Collectors.toList());

        if (CollUtil.isEmpty(clientCouponList)) {
            return List.of();
        }
        couponIds = clientCouponList.stream().map(ClientCoupon::getCouponId).collect(Collectors.toList());
        Map<Long, List<MarCouponCombo>> marCouponComboMapByCouponId = marCouponComboMapper.selectByMarCouponIds(couponIds).stream().collect(Collectors.groupingBy(MarCouponCombo::getMarCouponId));
        List<String> comboIds = orderCreateDTO.getShoppingCartList().stream().map(ShoppingCartsDto::getPackageId).collect(Collectors.toList());
        // 订单总价，小程序价格
        BigDecimal totalPrice = orderCreateDTO.getShoppingCartList().stream().map(item -> {
            // 计算套餐总价 购买数量*小程序商品价格
            return NumberUtil.mul(item.getQuantity(), item.getPrice());
        }).reduce(BigDecimal.ZERO, BigDecimal::add);

        clientCouponList = clientCouponList.stream().filter(item -> {
            // 判断优惠券适用套餐
            if (item.getCombo() == 0) {
                // 判断优惠券使用门槛
                if (!CouponTypeEnum.BABY_CUSTOMER.getCode().equals(item.getType())) {
                    if (NumberUtil.isLessOrEqual(totalPrice, new BigDecimal("0.01"))) {
                        return false;
                    }
                }
                return NumberUtil.isGreaterOrEqual(totalPrice, item.getThreshold());
            } else {
                List<String> couponComboIds = marCouponComboMapByCouponId.getOrDefault(item.getCouponId(), List.of()).stream().map(MarCouponCombo::getComboId).collect(Collectors.toList());
                if (CollUtil.containsAny(couponComboIds, comboIds)) {
                    // 判断优惠券使用门槛
                    Map<String, ShoppingCartsDto> shoppingCartsDtoMapByPackageId = orderCreateDTO.getShoppingCartList().stream().collect(Collectors.toMap(ShoppingCartsDto::getPackageId, item2 -> item2));
                    BigDecimal price = couponComboIds.stream().map(comboId -> {
                        ShoppingCartsDto orDefault = shoppingCartsDtoMapByPackageId.getOrDefault(comboId, null);
                        if (Objects.nonNull(orDefault)) {
                            return NumberUtil.mul(orDefault.getPrice(), orDefault.getQuantity());
                        }
                        return BigDecimal.ZERO;
                    }).reduce(BigDecimal.ZERO, BigDecimal::add);
                    if (!CouponTypeEnum.BABY_CUSTOMER.getCode().equals(item.getType())) {
                        if (NumberUtil.isLessOrEqual(price, new BigDecimal("0.01"))) {
                            return false;
                        }
                    }
                    return NumberUtil.isGreaterOrEqual(price, item.getThreshold());
                }
                return false;
            }
        }).collect(Collectors.toList());

        return clientCouponList;
    }

    /**
     * 计算最优的优惠券
     * 默认使用优惠金额最大或最接近达到使用条件的优惠券（若面额相同则优先使用先过期的券）
     *
     * @param priceOriginal 原价
     * @param clientCoupons 优惠券列表
     */
    @Override
    public ClientCouponBestDTO getBestClientCoupon(BigDecimal priceOriginal, List<ClientCoupon> clientCoupons) {
        // if (NumberUtil.isLessOrEqual(priceOriginal, new BigDecimal("0.01"))) {
        //     return new ClientCouponBestDTO();
        // }
        if (CollUtil.isEmpty(clientCoupons)) {
            return new ClientCouponBestDTO();
        }
        List<ClientCouponBestDTO> clientCouponDtos = BeanUtil.copyToList(clientCoupons, ClientCouponBestDTO.class);
        // 根据优惠券类型进行分组
        Map<Integer, List<ClientCouponBestDTO>> couponsByType = clientCouponDtos.stream().collect(Collectors.groupingBy(ClientCouponBestDTO::getDiscountsType));
        // 根据不同券类型计算价格
        List<ClientCouponBestDTO> clientCouponDtoList1 = couponsByType.entrySet().stream().map(item -> {
            Integer key = item.getKey();
            List<ClientCouponBestDTO> clientCouponDtoList = item.getValue();

            ClientCouponStrategy clientCouponStrategy = clientCouponStrategyFactory.getClientCouponStrategy(key);
            if (Objects.isNull(clientCouponStrategy)) {
                return new ClientCouponBestDTO();
            }
            ClientCouponBestDTO clientCoupon = clientCouponStrategy.couponStrategy(priceOriginal, clientCouponDtoList);
            return clientCoupon;
        }).collect(Collectors.toList());

        return this.getBestSortClientCoupon(clientCouponDtoList1);
    }

    @Override
    public ClientCouponBestDTO getBestSortClientCoupon(List<ClientCouponBestDTO> clientCouponDtoList) {
        return clientCouponDtoList.stream().sorted(Comparator.comparing(ClientCouponBestDTO::getDiscountedAfterPrice).thenComparing(item -> {
            Date validEndTime = item.getValidEndTime();
            DateTime dateTime = DateUtil.offsetDay(validEndTime, item.getPostponeDay());
            return dateTime;
        })).findFirst().orElse(new ClientCouponBestDTO());
    }

    /**
     * 使用优惠券后，计算单个套餐的价格
     * (单品原价 / 订单总价格(原价)) ×优惠券金额 ≈ 单品优惠
     *
     * @param amount        单品原价
     * @param totalPrice    订单总价格(原价)
     * @param discountMoney 优惠券金额
     * @return 单品原价-单品优惠额
     */
    @Override
    public BigDecimal calculateDiscountMoney(BigDecimal amount, BigDecimal totalPrice, BigDecimal discountMoney) {
        BigDecimal div = NumberUtil.div(amount, totalPrice);
        BigDecimal mul = NumberUtil.mul(div, Optional.ofNullable(discountMoney).orElse(BigDecimal.ZERO));

        BigDecimal sub = NumberUtil.sub(amount, mul);
        if (NumberUtil.isLess(sub, BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }
        return sub.setScale(2, BigDecimal.ROUND_DOWN);
    }

    /**
     * 修改优惠券状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatusById(Long id, Integer status) {
        clientCouponMapper.updateStatusById(id, status);
    }

    @Override
    public ClientCoupon getClientCouponCountdown() {
        String clientId = SecurityUtils.getClientId();
        String cityName = SecurityUtils.getCityName();
        // 用户所有的优惠券
        List<ClientCoupon> clientCouponList = clientCouponMapper.getClientCouponListByClientIdAndStatusType(clientId, ClientCouponStatusEnums.NORMAL.getCode(), cityName);
        DateTime start = DateUtil.date();
        DateTime end = DateUtil.offsetDay(DateUtil.date(), 1);
        clientCouponList = clientCouponList.stream().filter(item -> DateUtil.isIn(item.getValidEndTime(), start, end)).collect(Collectors.toList());

        Optional<ClientCoupon> minTimeEvent = clientCouponList.stream().min(Comparator.comparing(ClientCoupon::getValidEndTime));
        List<ClientCoupon> finalClientCouponList = clientCouponList;
        List<ClientCoupon> result = minTimeEvent.map(event ->
                finalClientCouponList.stream().filter(e -> DateUtil.isSameTime(e.getValidEndTime(), event.getValidEndTime())).collect(Collectors.toList())
        ).orElseGet(ArrayList::new);

        if (CollUtil.isEmpty(result)) {
            return null;
        }

        List<ClientCoupon> clientCouponFullReduction = result.stream().filter(item -> CouponDiscountsTypeEnum.FULL_REDUCTION.getType().equals(item.getDiscountsType())).collect(Collectors.toList());
        // 有满减券
        if (CollUtil.isNotEmpty(clientCouponFullReduction)) {
            // 有霸王免单券，优先用霸王免单券
            List<ClientCoupon> clientCouponBaby = clientCouponFullReduction.stream().filter(item -> CouponTypeEnum.BABY_CUSTOMER.getCode().equals(item.getType())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(clientCouponBaby)) {
                return CollUtil.getFirst(clientCouponBaby);
            }
            // 如果没有霸王免单券，用最大优惠券
            ClientCoupon clientCoupon = clientCouponFullReduction.stream().max(Comparator.comparing(ClientCoupon::getDiscounts)).orElse(null);
            return clientCoupon;
        }
        // 无满减券
        else {
            List<ClientCoupon> clientCouponDiscount = result.stream().filter(item -> CouponDiscountsTypeEnum.DISCOUNT.getType().equals(item.getDiscountsType())).collect(Collectors.toList());
            return CollUtil.getFirst(clientCouponDiscount);
        }
    }

    @Override
    public Boolean listNewIcon(String cityName) {
        String clientId = SecurityUtils.getClientId();
        log.info("listNewIcon:clientId:{},city:{}", clientId, cityName);
        List<MarCoupon> marCoupons = marCouponMapper.validList(clientId, cityName);
        List<Long> marCouponIds = marCoupons.stream().map(MarCoupon::getId).collect(Collectors.toList());
        log.info("listNewIcon:clientId:{},marCouponIds:{}", clientId, marCouponIds);
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(CacheConstants.MINAPP_COUPON_NEW_ICON_KEY + clientId);
        bloomFilter.tryInit(1000000, 0.03);
        for (Long marCouponId : marCouponIds) {
            // 判断是否包含, 若不包含则返回true
            if (!bloomFilter.contains(marCouponId)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<ComboListVO> computeEstimatedPrice(String machineId, List<ComboListVO> comboListVOS) {

        // 获取餐品价格
        List<String> comboId = comboListVOS.stream().map(ComboListVO::getComboId).collect(Collectors.toList());
        Map<String, Combo> comboMapByComboId = comboService.listByPackageIds(comboId).stream().collect(Collectors.toMap(Combo::getComboId, Function.identity()));

        OrderCreateDTO orderCreateDTO = new OrderCreateDTO();
        orderCreateDTO.setMachineId(machineId);

        for (ComboListVO comboListVO : comboListVOS) {
            ShoppingCartsDto shoppingCartsDto = new ShoppingCartsDto();
            shoppingCartsDto.setQuantity(1);
            shoppingCartsDto.setPackageId(comboListVO.getComboId());
            orderCreateDTO.setShoppingCartList(Collections.singletonList(shoppingCartsDto));
            String clientId = null;
            try {
                clientId = SecurityUtils.getClientId();
            } catch (InnerAuthException e) {
                log.info("computeEstimatedPrice,用户未登录时调用");
            }

            ClientCouponBestDTO clientCouponBestDTO = orderService.getClientCouponBestDTO(orderCreateDTO, clientId, comboMapByComboId);
            if (Objects.nonNull(clientCouponBestDTO)) {
                MarketingDTO marketing = comboListVO.getAppletComboInfoDto().getMarketing();
                marketing.setDiscountedAfterPrice(clientCouponBestDTO.getDiscountedAfterPrice());
                marketing.setClientCouponId(clientCouponBestDTO.getId());
            }
        }
        return comboListVOS;
    }

    @Override
    public List<ClientCoupon> fillBabyCouponDiscounts(OrderCreateDTO orderCreateDTO, List<ClientCoupon> availableCoupons) {
        BigDecimal price = CollUtil.getFirst(orderCreateDTO.getShoppingCartList()).getPrice();

        availableCoupons.stream()
                .filter(item -> CouponTypeEnum.BABY_CUSTOMER.getCode().equals(item.getType()))
                .forEach(item -> item.setDiscounts(price));

        return availableCoupons;
    }

    @Override
    public CouponPackVO findCouponPack(Long couponPackId) {
        CouponPackVO couponPackVO = new CouponPackVO();
        MarCouponPack marCouponPack = marCouponPackService.findById(couponPackId);
        List<MarCouponPackDetails> marCouponPackDetails = marCouponPackDetailsService.findByCouponPackId(couponPackId);
        List<CouponPackDetailsVO> couponPackDetailsVOS = new ArrayList<>();
        CouponPackDetailsVO couponPackDetailsVO = null;
        for (MarCouponPackDetails packDetailsVO : marCouponPackDetails) {
            couponPackDetailsVO = new CouponPackDetailsVO();
            couponPackDetailsVO.setCouponPackId(couponPackId);
            MarCoupon marCoupon = marCouponService.findById(packDetailsVO.getCouponId());
            couponPackDetailsVO.setMarCoupon(marCoupon);
            couponPackDetailsVO.setCouponCount(packDetailsVO.getCouponCount());
            log.info("couponPackDetailsVO：{}", couponPackDetailsVO);
            log.info("packDetailsVO：{}，packDetailsVO.getCouponCount()", packDetailsVO, packDetailsVO.getCouponCount());
            couponPackDetailsVOS.add(couponPackDetailsVO);
        }
        couponPackVO.setCouponPackDetailsVOS(couponPackDetailsVOS);
        couponPackVO.setMarCouponPack(marCouponPack);

        return couponPackVO;
    }

    @Override
    public List<ClientCoupon> findCouponCentre(Integer status, String clientId) {
        return clientCouponMapper.findCouponCentre(status, clientId);
    }

    @Override
    public List<ClientCoupon> findByIds(ArrayList<Long> marCouponIdList) {
        if (CollUtil.isEmpty(marCouponIdList)) {
            return List.of();
        }
        return clientCouponMapper.findByIds(marCouponIdList);
    }

    @Override
    public List<ClientCoupon> getActivitySignInsClientRecordsById(String clientId, List<Long> activitySignInsClientRecordsIdList) {
        if (CollUtil.isEmpty(activitySignInsClientRecordsIdList)) {
            return List.of();
        }
        return clientCouponMapper.getActivitySignInsClientRecordsById(clientId, activitySignInsClientRecordsIdList);
    }

}
